package boss.portal.service.impl.pro;

import boss.portal.dao.PublicCollectCountDao;
import boss.portal.dto.PublicCollectDto;
import boss.portal.dto.PublicSaveDto;
import boss.portal.entity.pro.PublicCollect;
import boss.portal.entity.pro.PublicCollectDetail;
import boss.portal.repository.PublicCollectDetailRepository;
import boss.portal.repository.PublicCollectRepository;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.*;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class PublicCollectServiceImpl{

    @Autowired
    private PublicCollectRepository publicCollectRepository;

    @Autowired
    private PublicCollectDetailRepository publicCollectDetailRepository;

    public Page<PublicCollect> queryPage(Pageable pageable, PublicCollectDto dto){
        Specification<PublicCollect> specification = new Specification<PublicCollect>() {
            @Override
            public Predicate toPredicate(Root<PublicCollect> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(dto.getSource())){
                    Path<Object> source = root.get("source");
                    Predicate predicateSource = criteriaBuilder.equal(source.as(String.class), dto.getSource());
                    predicates.add(predicateSource);
                }if(!StringUtils.isEmpty(dto.getTitle())){
                    Path<Object> title = root.get("title");
                    Predicate predicateTitle = criteriaBuilder.like(title.as(String.class), "%" + title + "%");
                    predicates.add(predicateTitle);
                }
                if (!StringUtils.isEmpty(dto.getSourceItemId())){
                    Path<Object> sourceItemId = root.get("sourceItemId");
                    Predicate predicateSourceItemId = criteriaBuilder.equal(sourceItemId.as(String.class), dto.getSourceItemId());
                    predicates.add(predicateSourceItemId);
                }
                if (!StringUtils.isEmpty(dto.getCollectStartTime())){
                    Path<Object> collectStartTime = root.get("collectStartTime");
                    Predicate startTime = criteriaBuilder.greaterThanOrEqualTo(collectStartTime.as(String.class), dto.getCollectStartTime());
                    predicates.add(startTime);
                }
                if(!StringUtils.isEmpty(dto.getCollectEndTime())){
                    Path<Object> collectEndTime = root.get("collectEndTime");
                    Predicate endTime = criteriaBuilder.lessThanOrEqualTo(collectEndTime.as(String.class), dto.getCollectEndTime());
                    predicates.add(endTime);
                }
                if (!StringUtils.isEmpty(dto.getMinSkuPrice()) && dto.getMinSkuPrice().compareTo(BigDecimal.ZERO)>0){
                    Path<Object> minSkuPrice = root.get("minSkuPrice");
                    Predicate predicateMinSkuPrice = criteriaBuilder.greaterThanOrEqualTo(minSkuPrice.as(BigDecimal.class), dto.getMinSkuPrice());
                    predicates.add(predicateMinSkuPrice);
                }
                if (!StringUtils.isEmpty(dto.getMaxSkuPrice()) && dto.getMaxSkuPrice().compareTo(BigDecimal.ZERO)>0){
                    Path<Object> maxSkuPrice = root.get("maxSkuPrice");
                    Predicate predicateMaxSkuPrice = criteriaBuilder.lessThanOrEqualTo(maxSkuPrice.as(BigDecimal.class), dto.getMaxSkuPrice());
                    predicates.add(predicateMaxSkuPrice);
                }
                if (!StringUtils.isEmpty(dto.getClaimStatus())){
                    Path<Object> claimStatus = root.get("claimStatus");
                    Predicate predicateclaimStatus = criteriaBuilder.equal(claimStatus.as(String.class), dto.getClaimStatus());
                    predicates.add(predicateclaimStatus);
                }
                if (!StringUtils.isEmpty(dto.getClaimPlatform())){
                    Path<Object> claimPlatform = root.get("claimPlatform");
                    Predicate predicateclaimPlatform = criteriaBuilder.equal(claimPlatform.as(String.class), dto.getClaimPlatform());
                    predicates.add(predicateclaimPlatform);
                }
                if (!StringUtils.isEmpty(dto.getRemark())){
                    Path<Object> remark = root.get("remark");
                    Predicate predicateremark = criteriaBuilder.like(remark.as(String.class), "%"+dto.getClaimPlatform()+"%");
                    predicates.add(predicateremark);
                }
                Predicate predicate = criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                return predicate;
            }
        };
        Page<PublicCollect> all = publicCollectRepository.findAll(specification, pageable);
        return all;
    }

    //查询详情
    public PublicCollectDetail querDetail(Long detailId){
        Optional<PublicCollectDetail> publicCollectDetail = publicCollectDetailRepository.findById(detailId);
        if (publicCollectDetail.isPresent()){
            return publicCollectDetail.get();
        }
        return null;
    }

    //删除
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id){
        try{
            Optional<PublicCollect> publicCollect = publicCollectRepository.findById(id);
            if (publicCollect.isPresent()){
                Long detailId = publicCollect.get().getDetailId();
                publicCollectDetailRepository.deleteById(detailId);
                publicCollectRepository.deleteById(id);
            }
        }catch (Exception e){
            log.error("删除公共采集产品error:"+e.getMessage());
            throw new RuntimeException("删除公共采集产品失败！");
        }
    }

    //添加备注
    public void addRemark(Long id,String remark){
        try{
            Optional<PublicCollect> publicCollect = publicCollectRepository.findById(id);
            if (!publicCollect.isPresent()){
                throw new RuntimeException("产品不存在！");
            }
            PublicCollect publicCollect1 = publicCollect.get();
            publicCollect1.setRemark(remark);
            publicCollectRepository.saveAndFlush(publicCollect1);

        }catch (Exception e){
            log.error("添加备注失败:"+e.getMessage());
            throw new RuntimeException("添加备注失败！");
        }

    }

    //统计

    public PublicCollectCountDao queryCount(){
        PublicCollectCountDao publicCollectCountDao = new PublicCollectCountDao();
        //all
        long all = publicCollectRepository.count();

        //claimed
        int claimed = publicCollectRepository.countByClaimStatus("claimed");

        //noClaimed
        int noClaimed = publicCollectRepository.countByClaimStatus("noClaimed");

        //collectFail
        int collectFail = publicCollectRepository.countByCollectStatus("fail");

        publicCollectCountDao.setAll((int)all);
        publicCollectCountDao.setClaimed(claimed);
        publicCollectCountDao.setCollectFail(collectFail);
        publicCollectCountDao.setNoClaimed(noClaimed);
        return publicCollectCountDao;
    }

    @Transactional(rollbackFor = Exception.class)
    public void addData(){
        for (int i=0;i<50;i++){
        PublicCollect publicCollect = new PublicCollect();
        PublicCollectDetail detail = new PublicCollectDetail();

        File file = new File("C:\\项目\\erp\\response.json");
        try{
            String str = null;
            FileInputStream in = new FileInputStream(file);
            byte[] buf = new byte[1024*1024*512];
            int length = 0;
            while ((length = in.read(buf)) != -1){
                str = new String(buf,0,length);
            }
            JSONObject jsonData = JSONUtil.parseObj(str);
            if ("200".equals(jsonData.getStr("code"))){

                    JSONObject data = jsonData.getJSONObject("data");
                    JSONObject result = data.getJSONObject("result");
                    detail.setSkuMap(result.getStr("sku_map"));
                    detail.setPrice(BigDecimal.valueOf(result.getLong("price")));
                    detail.setTitle(result.getStr("title"));
                    detail.setNotesText(result.getStr("detail"));
                    detail.setSku(result.getStr("sku"));
                    publicCollectDetailRepository.save(detail);
                    publicCollect.setTitle(detail.getTitle());
                    publicCollect.setDetailId(detail.getId());
                    publicCollectRepository.save(publicCollect);


            }
        }catch (Exception e){
            log.error("保存采集数据error:"+e);
            throw new RuntimeException("保存采集数据error");
        }
        }
    }

    /**
     * 保存或者更新数据
     * @param publicSaveDto
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateData(PublicSaveDto publicSaveDto){
        if (publicSaveDto.getPublicCollectDetail() != null){
            publicCollectDetailRepository.save(publicSaveDto.getPublicCollectDetail());
        }
        if (publicSaveDto.getPublicCollect() != null){
            publicSaveDto.getPublicCollect().setDetailId(publicSaveDto.getPublicCollectDetail().getId());
            publicCollectRepository.save(publicSaveDto.getPublicCollect());
        }
    }

    @Transactional
    public void delChoice(PublicCollectDto dto){
        Specification<PublicCollect> specification = new Specification<PublicCollect>() {
            @Override
            public Predicate toPredicate(Root<PublicCollect> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(dto.getSource())){
                    Path<Object> source = root.get("source");
                    Predicate predicateSource = criteriaBuilder.equal(source.as(String.class), dto.getSource());
                    predicates.add(predicateSource);
                }if(!StringUtils.isEmpty(dto.getTitle())){
                    Path<Object> title = root.get("title");
                    Predicate predicateTitle = criteriaBuilder.like(title.as(String.class), "%" + title + "%");
                    predicates.add(predicateTitle);
                }
                if (!StringUtils.isEmpty(dto.getSourceItemId())){
                    Path<Object> sourceItemId = root.get("sourceItemId");
                    Predicate predicateSourceItemId = criteriaBuilder.equal(sourceItemId.as(String.class), dto.getSourceItemId());
                    predicates.add(predicateSourceItemId);
                }
                if (!StringUtils.isEmpty(dto.getCollectStartTime())){
                    Path<Object> collectStartTime = root.get("collectStartTime");
                    Predicate startTime = criteriaBuilder.greaterThanOrEqualTo(collectStartTime.as(String.class), dto.getCollectStartTime());
                    predicates.add(startTime);
                }
                if(!StringUtils.isEmpty(dto.getCollectEndTime())){
                    Path<Object> collectEndTime = root.get("collectEndTime");
                    Predicate endTime = criteriaBuilder.lessThanOrEqualTo(collectEndTime.as(String.class), dto.getCollectEndTime());
                    predicates.add(endTime);
                }
                if (!StringUtils.isEmpty(dto.getMinSkuPrice()) && dto.getMinSkuPrice().compareTo(BigDecimal.ZERO)>0){
                    Path<Object> minSkuPrice = root.get("minSkuPrice");
                    Predicate predicateMinSkuPrice = criteriaBuilder.greaterThanOrEqualTo(minSkuPrice.as(BigDecimal.class), dto.getMinSkuPrice());
                    predicates.add(predicateMinSkuPrice);
                }
                if (!StringUtils.isEmpty(dto.getMaxSkuPrice()) && dto.getMaxSkuPrice().compareTo(BigDecimal.ZERO)>0){
                    Path<Object> maxSkuPrice = root.get("maxSkuPrice");
                    Predicate predicateMaxSkuPrice = criteriaBuilder.lessThanOrEqualTo(maxSkuPrice.as(BigDecimal.class), dto.getMaxSkuPrice());
                    predicates.add(predicateMaxSkuPrice);
                }
                if (!StringUtils.isEmpty(dto.getClaimStatus())){
                    Path<Object> claimStatus = root.get("claimStatus");
                    Predicate predicateclaimStatus = criteriaBuilder.equal(claimStatus.as(String.class), dto.getClaimStatus());
                    predicates.add(predicateclaimStatus);
                }
                if (!StringUtils.isEmpty(dto.getClaimPlatform())){
                    Path<Object> claimPlatform = root.get("claimPlatform");
                    Predicate predicateclaimPlatform = criteriaBuilder.equal(claimPlatform.as(String.class), dto.getClaimPlatform());
                    predicates.add(predicateclaimPlatform);
                }
                if (!StringUtils.isEmpty(dto.getRemark())){
                    Path<Object> remark = root.get("remark");
                    Predicate predicateremark = criteriaBuilder.like(remark.as(String.class), "%"+dto.getClaimPlatform()+"%");
                    predicates.add(predicateremark);
                }
                Predicate predicate = criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                return predicate;
            }
        };
        List<PublicCollect> all = publicCollectRepository.findAll(specification);
        if (!CollectionUtils.isEmpty(all)){
            all.forEach(n->{
                publicCollectRepository.deleteById(n.getId());
                publicCollectDetailRepository.deleteById(n.getDetailId());
            });
        }
    }

    public static void main(String[] args) {
        File file = new File("C:\\项目\\erp\\response.json");
        try{
            String str = null;
            FileInputStream in = new FileInputStream(file);
            byte[] buf = new byte[1024*1024*512];
            int length = 0;
            while ((length = in.read(buf)) != -1){
                str = new String(buf,0,length);
            }
            JSONObject jsonData = JSONUtil.parseObj(str);
            JSONObject data = jsonData.getJSONObject("data");
            JSONObject result = data.getJSONObject("result");
            System.out.println(result.getStr("sku_map"));
        }catch (Exception e){

        }
    }
}
